﻿using System.Collections.Generic;
using LoungeRepo.Contracts.Core;
using LoungeRepo.Contracts.Normalizer;

namespace LoungeRepo.Normalizer
{
    public class EntityNormalizer : IEntityNormalizer
    {
        private readonly ReportEntityDelegate reportEntity;
        private readonly EntityResolutionRequestDelegate resolveEntityReference;


        public EntityNormalizer(EntityResolutionRequestDelegate resolveEntityReference, ReportEntityDelegate reportEntity)
        {
            this.reportEntity = reportEntity;
            this.resolveEntityReference = resolveEntityReference;
        }


        public IEnumerable<INormalizedEntity> Normalize(object entityObject)
        {
            var normalizer = new ObjectGraphNormalizer(reportEntity);

            ILoungeRepoEntityIdentity entityIdentity;
            if (EntityRecognizer.TryExtractEntityIdentity(entityObject, out entityIdentity))
                return normalizer.NormalizeEntityGraph(entityObject, entityIdentity);

            throw new NormalizerException(string.Format("Invalid entity type {0}! Must implement ILoungeRepoEntityIdentity", entityObject.GetType().FullName));
        }


        public object Denormalize(INormalizedEntity normalizedEntity)
        {
            return new ObjectGraphDenormalizer(this.resolveEntityReference, this.reportEntity)
                        .Denormalize(normalizedEntity);
        }


        public bool TryExtractEntityIdentity(object entityObject, out ILoungeRepoEntityIdentity entityIdentity)
        {
            return EntityRecognizer.TryExtractEntityIdentity(entityObject, out entityIdentity);
        }
    }
}
